<?php
//edit by peter 2017-04-06
include_once $_SERVER ['DOCUMENT_ROOT'] . '/upacp_demo_b2b/sdk/acp_service.php';
final class ectools_payment_plugin_unionpayb2b extends ectools_payment_app implements ectools_interface_payment_app{
    /*
     *以下的内容可以改变成自己想要接入的网关名称，最主要的就是[$app_rpc_key：(一般就是当前类名)]的值。
     */
    //支付接口名称，一般不被前台或者后台显示使用
    public $name = '企业网银网关支付';
    //支付接口应用名称，一般不被前台或者后台显示使用
    public $app_name = '企业网银网关支付';
    //支付接口的唯一标示，用于数据对应取值，一般用英文表示
    public $app_key = 'unionpayb2b';
    /** 中心化统一的key **/
    public $app_rpc_key = 'unionpayb2b';
    //用于前后台显示在页面上的名称
    public $display_name = '企业网银网关支付';
    public $curname = 'CNY';
    public $ver = '1.0';
    /**
     * @var array 扩展参数
     */
    public $supportCurrency = array("CNY"=>"CNY");
    /**
     * @var string 当前支付方式所支持的平台
     * ispc标准版 iswap触屏版 iscommon通用版
     */
    public $platform = 'ispc';

    /*
     * is_fields_valiad:验证提交表单数据的正确性
     */
    function is_fields_valiad()
    {
        return true;
    }

    /*
     *intro:前台在线支付列表相应项目的说明
     *前台支付方式列表关于此支付方式的简介
     */
    function intro()
    {
        return '<b><h3>'.app::get('ectools')->_('银联企业网银支付').'</h3></b>';
    }

    /*
     *admin_intro:显示支付接口后台的信息
     *后台支付方式列表关于此支付方式的简介 
     */
    function admin_intro()
    {
        return app::get('ectools')->_('银联企业网银支付产品（简称B2B支付产品）以商业银行企业网银为基础，为B2B电子商务提供全面的网上支付及清算对账服务。支持境内外商户和机构的企业网银B2B支付交易，支持消费及其后续类相关交易，包括B2B消费、退货和交易状态查询，与商户直联各银行网银的用户体验一致； 商户端接入各银行网银的接口统一； 清算、对账、退款等业务处理统一,目前支持14家银行：工商银行、农业银行、建设银行、交通银行、招商银行、中信银行、民生银行、华夏银行、光大银行、中国银行、浦发银行、平安银行、东亚银行、广发银行。 后续企业网银的支持数量将持续增加。');
    }

    /*
     *以下构造函数主要是配置回调路径，主要是修改诸如这样的类名“ectools_payment_plugin_alipay_server”，改为自己定义的。
     */
    public function __construct($app)
    {
        parent::__construct($app);

        $this->notify_url = kernel::openapi_url('openapi.ectools_payment/parse/' . $this->app->app_id . '/ectools_payment_plugin_unionpayb2b_server', 'callback');
        if (preg_match("/^(http):\/\/?([^\/]+)/i", $this->notify_url, $matches)){
            $this->notify_url = str_replace('http://','',$this->notify_url);
            $this->notify_url = preg_replace("|/+|","/", $this->notify_url);
            $this->notify_url = "http://" . $this->notify_url;
        } else {
            $this->notify_url = str_replace('https://','',$this->notify_url);
            $this->notify_url = preg_replace("|/+|","/", $this->notify_url);
            $this->notify_url = "https://" . $this->notify_url;
        }
        $this->callback_url = kernel::openapi_url('openapi.ectools_payment/parse/' . $this->app->app_id . '/ectools_payment_plugin_unionpayb2b', 'callback');
        if (preg_match("/^(http):\/\/?([^\/]+)/i", $this->callback_url, $matches)){
            $this->callback_url = str_replace('http://','',$this->callback_url);
            $this->callback_url = preg_replace("|/+|","/", $this->callback_url);
            $this->callback_url = "http://" . $this->callback_url;
        }else{
            $this->callback_url = str_replace('https://','',$this->callback_url);
            $this->callback_url = preg_replace("|/+|","/", $this->callback_url);
            $this->callback_url = "https://" . $this->callback_url;
        }
	
        $this->submit_url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->frontTransUrl;
        $this->submit_method = 'POST';
        $this->submit_charset = 'utf-8';
	
    }

    //setting:设置后台的显示项目（表单项目）
    public function setting()
    {
        return array(
            'pay_name'=>array(
                'title'=>app::get('ectools')->_('支付方式名称'),
                'type'=>'string',
                'validate_type' => 'required',
            ),
            'mer_id'=>array(
                'title'=>app::get('ectools')->_('商户号'),
                'type'=>'string',
                //'validate_type' => 'required',
            ),
	    //证书后台上传固定位置
	    /*
	    'sdk_sign_cert_path'=>array(
                'title'=>app::get('ectools')->_('签名证书'),
                'type'=>'file',
                'validate_type' => 'required',
                'label'=>app::get('ectools')->_('文件后缀名为.pfx'),
            ),
	    */
            'order_by' =>array(
                'title'=>app::get('ectools')->_('排序'),
                'type'=>'string',
                'label'=>app::get('ectools')->_('整数值越小,显示越靠前,默认值为1'),
            ),
            'pay_desc'=>array(
                'title'=>app::get('ectools')->_('描述'),
                'type'=>'html',
                'includeBase' => true,
            ),
	    //add by peter 2017-04-07 必须加pay_type,且须设为是(在线支付),否则不会跳入dopay方法
	    //此处隐藏, 在 custom/ectools/controller/payment/cfgs.php中控制默认值
	    /*
	    'pay_type'=>array(
		'title'=>app::get('ectools')->_('支付类型(是否在线支付)'),
		'type'=>'radio',
                'options'=>array('false'=>app::get('ectools')->_('否'),'true'=>app::get('ectools')->_('是')),
		'name'=>'pay_type',
	    ),
	    */
            'status'=>array(
                'title'=>app::get('ectools')->_('是否开启此支付方式'),
                'type'=>'radio',
                'options'=>array('false'=>app::get('ectools')->_('否'),'true'=>app::get('ectools')->_('是')),
                'name' => 'status',
            ),
        );
    }

    /*
     *dopay:支付表单的提交方式
     *提交支付信息的接口 
     * @param array 提交信息的数组 
     * @return mixed false or null 
     * $this->add_field() 
     */
    public function dopay($payment){
	header ( 'Content-type:text/html;charset=utf-8' );
	$params = array(
		//版本号,固定5.1.0
		'version' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->version,                 
		//编码方式,UTF-8|GBK|GB2312|GB18030
		'encoding' => 'UTF-8',
		//交易类型,01消费,其它请查阅全渠道平台产品接口规范
		'txnType' => '01',
		//交易子类,依据实际交易类型填写,B2B取01自助消费
		'txnSubType' => '01',
		//产品类型,000202为B2B
		'bizType' => '000202',
		//前台通知地址,前台类交易需上送,前台返回商户结果时使用
		'frontUrl' => str_replace("{ipaddress}",$_SERVER['HTTP_HOST'], com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->frontUrl),
		//后台通址,后台返回商户结果时使用
		'backUrl' => str_replace("{ipaddress}",$_SERVER['HTTP_HOST'], com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backUrl),
		//签名方法,非对称签名,01RSA,HASH散列算法,11SHA-256,12SM3
		'signMethod' => com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod,
		//渠道类型,05语音,07互联网,08移动
		'channelType' => '07',
		//接入类型,0商户直连接入,1收单机构接入,2平台商户接入
		'accessType' => '0',
		//交易币种,156人民币
		'currencyCode' => '156',
		//TODO 以下信息需要填写
		'merId' =>$this->getConf('mer_id',__CLASS__), 
		//注意这里是传入商户订单号(付款单号?)
		'orderId' => $payment['payment_id'],
		//订单发送时间,商户发送交易时间:取payment表的支付开始时间
		'txnTime' => date('YmdHis',$payment['t_begin']),
		//交易金额,单位为分
		'txnAmt' => number_format($payment['cur_money'],2,".","")*100,
		//支付超时时间,超过此时间用户支付成功的交易,不通知商户,系统自动退款,约5工作日到账
		'payTimeout' => date('YmdHis', strtotime('+15 minutes')), 
	);

	com\unionpay\acp\sdk\AcpService::sign ( $params );
	$uri = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->frontTransUrl;
	$html_form = com\unionpay\acp\sdk\AcpService::createAutoFormHtml( $params, $uri );
	echo $html_form;
	exit();
    }

    /*
     *callback:支付后返回后处理的事件的动作
     *回调函数: 接受银联返回来的数据
     *支付后返回后处理的事件的动作 
     * @params array - 所有返回的参数，包括POST和GET 
     * @return null
     */
    public function callback(&$recv){
	$logger=com\unionpay\acp\sdk\LogUtil::getLogger();
	//银联返回整个$_POST,内含各种信息
	$logger->LogInfo("receive back notify: " . com\unionpay\acp\sdk\createLinkString ( $_POST, false, true ));
        $objMath = kernel::single('ectools_math');
        $money=$objMath->number_multiple(array($_POST['settleAmt'], 0.01));
	//商户号
        $merid = $this->getConf('mer_id', __CLASS__);
        $sign=$_POST['signature'];       
        $sign_method=$_POST['signMethod']; 
        $ret['payment_id'] =$_POST['orderId'];
        $ret['account'] = $_POST['merId'];
        $ret['bank'] = app::get('ectools')->_('银联');
        $ret['pay_account'] = app::get('ectools')->_('付款帐号');
        $ret['currency'] = 'CNY';
        $ret['money'] = $money;
        $ret['paycost'] = '0.000';
        $ret['cur_money'] =$money;
        $ret['tradeno'] = $_POST['traceNo'];
        // $ret['t_payed'] = strtotime($_POST['settleDate']) ? strtotime($_POST['settleDate']) : time();
        $ret['t_payed'] = time();
        $ret['pay_app_id'] = 'unionpayb2b';
        $ret['pay_type'] = 'online';
        $ret['memo'] = 'unionpayb2b';
        //校验签名
	$ret['status']='failed';
	if (isset($sign)){   
		if (com\unionpay\acp\sdk\AcpService::validate ( $_POST ) && $_POST['respCode']==00) {
		    $ret['status'] = 'succ';
		}
	}
	
        //判断respCode=00、A6后，对涉及资金类的交易，请再发起查询接口查询，确定交易成功后更新数据库。
	//待定
	return $ret;
    }


    //gen_form:生成支付表单 - 自动提交(点击链接提交的那种方式，通常用于支付方式列表)
    public function gen_form()
    {
      $tmp_form='<a href="javascript:void(0)" onclick="document.applyForm.submit();">'.app::get('ectools')->_('立即申请').'</a>';
      $tmp_form.="<form name='applyForm' method='".$this->submit_method."' action='" . $this->submit_url . "' target='_blank'>";
      // 生成提交的hidden属性
      foreach($this->fields as $key => $val)
      {    
            $tmp_form.="<input type='hidden' name='".$key."' value='".$val."'>";
      }

      $tmp_form.="</form>";

      return $tmp_form;

    }
}
